package org.uc3m.pfc.marker.manager;

import java.util.ArrayList;
import java.util.List;

import org.opencv.android.CameraBridgeViewBase;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.uc3m.pfc.activity.MainActivity;
import org.uc3m.pfc.command.CommandManager;
import org.uc3m.pfc.command.ICommandManager;
import org.uc3m.pfc.data.Action;
import org.uc3m.pfc.device.DeviceManager;
import org.uc3m.pfc.device.IDeviceManager;
import org.uc3m.pfc.lifecycle.LifeCycle;
import org.uc3m.pfc.lifecycle.State;

import static org.uc3m.pfc.lifecycle.State.*;
import org.uc3m.pfc.marker.detection.IMarkerDetector;
import org.uc3m.pfc.marker.detection.Marker;
import org.uc3m.pfc.marker.detection.MarkerDetector;

import android.content.Context;
import android.media.AudioManager;
import android.os.Handler;
import android.util.Log;

/**
 * 
 * @author esteban
 *
 */
public final class MarkerManager extends LifeCycle implements IMarkerManager {

	/** Tag for log instance. */
	private static final String TAG = MarkerManager.class.getSimpleName();
	
	private static IMarkerManager instance;
	

    /** Marker detector instance. */
    private IMarkerDetector markerDetector;
    /** Marker painter instance. */
    private IMarkerPainter markerPainter;
    /** Marker filter instance. */
    private IMarkerFilter markerFilter;
    
    /** Command manager instance. */
    private ICommandManager commandManager;
    
 

    /**
     * Private default constructor.
     */
    private MarkerManager() {
    	
    	this.markerDetector = MarkerDetector.getInstance();
    	this.markerFilter = MarkerFilter.getInstance();
    	this.markerPainter = MarkerPainter.getInstance();
    	
    	this.commandManager = CommandManager.getInstance();
    	this.commandManager.setMarkerManager(this);
    	
    	this.setState(detecting);
	}
    
    public static IMarkerManager getInstance() {
    	
    	if (instance == null) {
    		instance = new MarkerManager();
    	}
    	
		return instance;
	}
    
	@Override
	public Mat processFrame(final Mat frame) {

		List<Marker> markers = markerDetector.detectMarkers(frame);

		if (!markers.isEmpty()) {

			Marker marker = markerFilter.filterMultiplesMarkers(markers, frame);

			markerPainter.paintInfo(marker, frame);
			markerPainter.paintCircle(marker, frame);

			switch (this.getState()) {
			case detecting:

				markerFilter.enableByTime(marker.id);

				if (((MarkerFilter) markerFilter).getSubstate() 
						== trackingFinished) {

					Log.i(TAG, "Marker id encontrado: " + marker.id);
					markerFilter.setId(marker.id);

					this.setState(processing);

					commandManager.executeCommand(marker.id);
				}

				break;

			case processing:
				// TODO clear?

				// markerPainter.resetInfo();
				// TODO clear?
				break;

			default:
				// state not allowed
				break;
			}

		} else { // empty

			if (this.getState() == detecting) {
			
				markerPainter.resetInfo();
			}
			
			markerFilter.resetTimer();
			
		}

		return frame;
	}

	@Override
	public void setState(final State pstate) {
	
		super.setState(pstate);

		((MarkerPainter) markerPainter).setState(pstate);
		((MarkerFilter) markerFilter).setState(pstate);

	}
	
}
